"""
基础Repository类
"""
from typing import Generic, TypeVar, Type, Optional, List, Dict, Any
from datetime import datetime
from sqlalchemy.orm import Session
from sqlalchemy import and_, or_

from app.core.database import Base
from app.core.exceptions import NotFoundException

T = TypeVar('T', bound=Base)

class BaseRepository(Generic[T]):
    """基础Repository类"""
    
    def __init__(self, db: Session, model: Type[T]):
        self.db = db
        self.model = model
    
    def get_by_id(self, id: int) -> Optional[T]:
        """根据ID获取记录"""
        return self.db.query(self.model).filter(
            and_(
                self.model.id == id,
                self.model.is_deleted == False
            )
        ).first()
    
    def get_all(self, skip: int = 0, limit: int = 100) -> List[T]:
        """获取所有记录"""
        return self.db.query(self.model).filter(
            self.model.is_deleted == False
        ).offset(skip).limit(limit).all()
    
    def create(self, obj_in: Dict[str, Any]) -> T:
        """创建记录"""
        obj = self.model(**obj_in)
        self.db.add(obj)
        self.db.commit()
        self.db.refresh(obj)
        return obj
    
    def update(self, id: int, obj_in: Dict[str, Any]) -> Optional[T]:
        """更新记录"""
        obj = self.get_by_id(id)
        if not obj:
            return None
        
        # 更新版本号
        obj_in['version'] = obj_in.get('version', obj.version) + 1
        
        for key, value in obj_in.items():
            if hasattr(obj, key):
                setattr(obj, key, value)
        
        self.db.commit()
        self.db.refresh(obj)
        return obj
    
    def delete(self, id: int) -> bool:
        """软删除记录"""
        obj = self.get_by_id(id)
        if not obj:
            return False
        
        obj.is_deleted = True
        obj.updated_at = datetime.utcnow()
        self.db.commit()
        return True
    
    def count(self) -> int:
        """统计记录数量"""
        return self.db.query(self.model).filter(
            self.model.is_deleted == False
        ).count()
    
    def get_by_field(self, field_name: str, value: Any) -> Optional[T]:
        """根据字段名获取记录"""
        if not hasattr(self.model, field_name):
            return None
        
        filter_condition = getattr(self.model, field_name) == value
        return self.db.query(self.model).filter(
            and_(
                filter_condition,
                self.model.is_deleted == False
            )
        ).first()
    
    def search(self, keyword: str, search_fields: List[str]) -> List[T]:
        """搜索记录"""
        if not search_fields:
            return []
        
        conditions = []
        for field in search_fields:
            if hasattr(self.model, field):
                field_attr = getattr(self.model, field)
                if hasattr(field_attr, 'contains'):
                    conditions.append(field_attr.contains(keyword))
        
        if not conditions:
            return []
        
        return self.db.query(self.model).filter(
            and_(
                or_(*conditions),
                self.model.is_deleted == False
            )
        ).all()